/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * ChequeEditor1.java
 *
 * Created on 07/04/2010, 19:41:43
 */

package com.power.powercash;

import com.db4o.ObjectContainer; 
import com.db4o.ObjectSet;
import com.power.utils.Searchable;
import com.power.utils.StringUtil;
import com.power.utils.ValorExtenso;
import com.power.visual.FindBox;
import com.power.visual.PaintStyle;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Date;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.SwingConstants;
import net.java.dev.transparentlayout.TransparentLayout;

/**
 *
 * @author Juno
 */
public class ChequeEditor
    extends javax.swing.JPanel
    implements PropertyChangeListener {

  private Font tahoma;

  private ObjectContainer db;

  private Cheque selected;

  private double value;


    /** Creates new form ChequeEditor1 */
    public ChequeEditor(ObjectContainer db) {
      if(db == null)
        throw new IllegalArgumentException("DB must be NOT NULL.");

      selected = null;
      value = -1;
      tahoma = new Font("Tahoma", Font.BOLD + Font.ITALIC, 12);
      this.db = db;
      initComponents();
      loadBanks();
      loadCheques();
      loadMoedas();

      StringSearchable s = new StringSearchable("Nominal");
      ObjectSet set = db.queryByExample(s);
      if(set == null || set.isEmpty())
        db.store(s);
      else
        s = (StringSearchable) set.get(0);
      nominalField.setSearchable(s);

      s = new StringSearchable("Finalidade");
      set = db.queryByExample(s);
      if(set == null || set.isEmpty())
        db.store(s);
      else
        s = (StringSearchable) set.get(0);
      finalidadeField.setSearchable(s);
    }


    private void loadBanks()
    {
      ObjectSet set = db.query(Banco.class);
      if(set == null || set.isEmpty())
        bancoBox.setModel(new DefaultComboBoxModel());
      else
        bancoBox.setModel(new DefaultComboBoxModel(set.toArray()));
    }


    private void loadCheques()
    {
      ObjectSet set = db.query(Cheque.class);
      if(set == null || set.isEmpty())
        chequesBox.setModel(new DefaultComboBoxModel());
      else
        chequesBox.setModel(new DefaultComboBoxModel(set.toArray()));
    }


    private void loadMoedas()
    {
      ObjectSet set = db.queryByExample(Moeda.DOLLAR);
      if(set.size() > 1 || set.isEmpty()) {
        while(set.hasNext())
          db.delete(set.next());
        db.store(Moeda.DOLLAR);
      }
      set = db.queryByExample(Moeda.EURO);
      if(set.size() > 1 || set.isEmpty()) {
        while(set.hasNext())
          db.delete(set.next());
        db.store(Moeda.EURO);
      }
      set = db.queryByExample(Moeda.REAL);
      if(set.size() > 1 || set.isEmpty()) {
        while(set.hasNext())
          db.delete(set.next());
        db.store(Moeda.REAL);
      }
      set = db.query(Moeda.class);

      moedaBox.setModel(new DefaultComboBoxModel(set.toArray()));
      moedaBox.setSelectedItem(Moeda.REAL);
      this.limparButtonActionPerformed(null);
    }


    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
  @SuppressWarnings("unchecked")
  private void initComponents() {

    PaintStyle ps = PaintStyle.GRADIENT_RED;
    ps.setFont(new Font("Tahoma", Font.BOLD, 15));
    titleLabel = new com.power.visual.BlackLabel(
      ps, "     Cheques");
    numberLabel = new javax.swing.JLabel();
    numberField = new javax.swing.JTextField();
    bancoLabel = new javax.swing.JLabel();
    bancoBox = new javax.swing.JComboBox();
    moedaLabel = new javax.swing.JLabel();
    moedaBox = new javax.swing.JComboBox();
    valorLabel = new javax.swing.JLabel();
    valorField = new javax.swing.JTextField();
    finalidadeLabel = new javax.swing.JLabel();
    emissaoDate = new org.jdesktop.swingx.JXDatePicker();
    lancFuturoLabel = new javax.swing.JLabel();
    futureDate = new org.jdesktop.swingx.JXDatePicker();
    consultarButton = new com.power.visual.BlackButton();
    gravarButton = new com.power.visual.BlackButton();
    statusBar = new javax.swing.JLabel();
    finalidadeField = new com.power.visual.FindBox();
    emissaoLabel = new javax.swing.JLabel();
    extensoLabel = new javax.swing.JLabel();
    nominalField = new com.power.visual.FindBox();
    nominalLabel = new javax.swing.JLabel();
    extensoField = new javax.swing.JTextField();
    moedaButton = new javax.swing.JButton();
    bancoButton = new javax.swing.JButton();
    removerButton = new com.power.visual.BlackButton();
    selcheque = new javax.swing.JLabel();
    chequesBox = new javax.swing.JComboBox();

    setLayout(new TransparentLayout());

    titleLabel.setText("     Cheques");
    titleLabel.setHorizontalAlignment(SwingConstants.LEFT);
    titleLabel.setImageIcon(ImageSet.CHEQUE);
    add(titleLabel, new Rectangle(0, 0, 590, 50));

    numberLabel.setText(" N� do Cheque");
    //jLabel1.setFont(tahoma);
    add(numberLabel, new Rectangle(190, 110, 120, 20));

    numberField.setFont(new Font("Monospaced", Font.PLAIN, 12));
    numberField.setHorizontalAlignment(javax.swing.JTextField.RIGHT);
    numberField.setToolTipText("Informe o n� do cheque sem pontos ou tra�os.");
    add(numberField, new Rectangle(190, 130, 120, 20));

    bancoLabel.setText(" Banco");
    //bancoLabel.setFont(tahoma);
    add(bancoLabel, new Rectangle(10, 110, 150, 20));

    bancoBox.setToolTipText("Selecione o Banco do Cheque");
    add(bancoBox, new Rectangle(10, 130, 150, 20));

    moedaLabel.setText(" Moeda");
    //jLabel3.setFont(tahoma);
    add(moedaLabel, new Rectangle(320, 110, 90, 20));

    moedaBox.setToolTipText("Selecione a Moeda de emiss�o do Cheque");
    add(moedaBox, new Rectangle(320, 130, 90, 20));

    valorLabel.setText(" Valor");
    //jLabel4.setFont(tahoma);
    add(valorLabel, new Rectangle(440, 110, 140, 20));

    valorField.setHorizontalAlignment(SwingConstants.RIGHT);
    valorField.setFont(new Font("Monospaced", Font.PLAIN, 12));
    valorField.setToolTipText("Informe o valor do Cheque");
    valorField.addActionListener(new java.awt.event.ActionListener() {
      @Override
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        valorFieldActionPerformed(evt);
      }
    });
    valorField.addFocusListener(new FocusAdapter() {
      @Override
      public void focusGained(FocusEvent fe)
      {
        String text = valorField.getText();
        if(text == null || text.equals(""))
        return;

        valorField.select(0, text.length());
      }
      @Override
      public void focusLost(FocusEvent fe)
      {
        valorFieldActionPerformed(null);
      }
    });
    add(valorField, new Rectangle(440, 130, 140, 20));

    finalidadeLabel.setText("Finalidade");
    //jLabel5.setFont(tahoma);
    add(finalidadeLabel, new Rectangle(10, 270, 310, 20));

    emissaoDate.setFormats("dd/MM/yyyy");
    emissaoDate.setToolTipText("Seleciona a data de emiss�o do cheque");
    add(emissaoDate, new Rectangle(330, 290, 120, 20));

    lancFuturoLabel.setText("Bom para:");
    //jLabel6.setFont(tahoma);
    add(lancFuturoLabel, new Rectangle(460, 270, 120, 20));

    futureDate.setFormats("dd/MM/yyyy");
    futureDate.setToolTipText("Selecione a data de desconto, caso seja pr�-datado.");
    add(futureDate, new Rectangle(460, 290, 120, 20));

    consultarButton.setText("Remover");
    consultarButton.setToolTipText("Limpa todos os campos");
    consultarButton.setImageIcon(ImageSet.REMOVE);
    consultarButton.addActionListener(new java.awt.event.ActionListener() {
      @Override
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        removerButtonActionPerformed(evt);
      }
    });
    add(consultarButton, new Rectangle(390, 340, 120, 30));

    gravarButton.setText(" Gravar");
    gravarButton.setToolTipText("Grava o cheque com os dados informados");
    gravarButton.setImageIcon(ImageSet.ADD);
    gravarButton.addActionListener(new java.awt.event.ActionListener() {
      @Override
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        gravarButtonActionPerformed(evt);
      }
    });
    add(gravarButton, new Rectangle(70, 340, 120, 30));

    statusBar.setForeground(new java.awt.Color(70, 70, 70));
    statusBar.setFont(new Font("Monospaced", Font.PLAIN, 12));
    statusBar.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(150, 150, 150), 1, true));
    add(statusBar, new Rectangle(0, 380, 590, 20));

    finalidadeField.setToolTipText("<HTML><h3>Informe a finalidade do cheque</h3>" +
        "- Pressione <b>PBAIXO</b> para listar todos;<br>" +
        "- Pressione <b>CTRL + ENTER</b> para adicionar novo registro;<br>" +
        "- Pressione <b>CTRL + DELETE</b> para remover um registro.<HTML>");
    finalidadeField.addPropertyChangeListener(this);
    add(finalidadeField, new Rectangle(10, 290, 310, 20));

    emissaoLabel.setText(" Data Emiss�o");
    //jLabel8.setFont(tahoma);
    add(emissaoLabel, new Rectangle(330, 270, 120, 20));

    extensoLabel.setText(" Valor por Extenso");
    //jLabel9.setFont(tahoma);
    add(extensoLabel, new Rectangle(10, 160, 570, 20));

    nominalField.setSearchable((Searchable) new Historicos());
    nominalField.setToolTipText("<HTML><h3>Informe o nome caso o cheque seja nominal.</h3>" +
        "- Pressione <b>PBAIXO</b> para listar todos;<br>" +
        "- Pressione <b>CTRL + ENTER</b> para adicionar novo registro;<br>" +
        "- Pressione <b>CTRL + DELETE</b> para remover um registro.<HTML>");
    nominalField.addPropertyChangeListener(this);
    add(nominalField, new Rectangle(10, 240, 570, 20));

    nominalLabel.setText(" Nominal  �");
    //jLabel10.setFont(tahoma);
    add(nominalLabel, new Rectangle(10, 220, 570, 20));

    extensoField.setEditable(false);
    extensoField.setToolTipText("Mostra o valor do cheque por extenso");
    Font sammy = null;
    try {
      sammy = Font.createFont(Font.TRUETYPE_FONT,
        this.getClass()
        .getResourceAsStream("fonts/ambiente.ttf"));
    } catch(Exception ex) {
      ex.printStackTrace();
      System.exit(1);
    }
    extensoField.setFont(sammy.deriveFont(Font.PLAIN, 18f));
    add(extensoField, new Rectangle(10, 180, 570, 30));

    moedaButton.setText("...");
    moedaButton.setToolTipText("Clique para Abrir o Editor de Moedas");
    moedaButton.addActionListener(new java.awt.event.ActionListener() {
      @Override
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        moedaButtonActionPerformed(evt);
      }
    });
    add(moedaButton, new Rectangle(410, 130, 20, 20));

    bancoButton.setText("...");
    bancoButton.setToolTipText("Clique para Abrir o Editor de Bancos");
    bancoButton.addActionListener(new java.awt.event.ActionListener() {
      @Override
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        bancoButtonActionPerformed(evt);
      }
    });
    add(bancoButton, new Rectangle(160, 130, 20, 20));

    removerButton.setText(" Limpar");
    removerButton.setToolTipText("Limpa todos os campos");
    removerButton.setImageIcon(ImageSet.TRASH);
    removerButton.addActionListener(new java.awt.event.ActionListener() {
      @Override
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        limparButtonActionPerformed(evt);
      }
    });
    add(removerButton, new Rectangle(230, 340, 120, 30));

    selcheque.setText(" Selecionar Cheque");
    //bancoLabel.setFont(tahoma);
    add(selcheque, new Rectangle(10, 70, 130, 20));

    chequesBox.setToolTipText("Selecione um cheque cadastrado para Edi��o/Remo��o.");
    chequesBox.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        chequesComboActionPerformed(e);
      }
    });
    add(chequesBox, new Rectangle(150, 70, 430, 20));
  }// </editor-fold>


    private void valorFieldActionPerformed(java.awt.event.ActionEvent evt) {
      StringUtil su = new StringUtil(valorField.getText());
      String s = null;
      s = su.replaceAll("R$  ", "");
      s = su.replaceAll(",", ".");
      //System.out.println(su.getString());
      Moeda moeda = Moeda.REAL;
      value = -1;
      try {
        value = Double.parseDouble(su.getString());
        if(value < 0)
          throw new NumberFormatException();
      } catch(NumberFormatException ne) {
        this.setStatus("Valor inv�lido.");
        return;
      }

      su.setString(Formatter.format(moeda, 2, value, 2));
      valorField.setText(su.getString());

      ValorExtenso ve = new ValorExtenso(value);
      ve.setNomeSingular(moeda.getName());
      ve.setNomePlural(moeda.getNomePlural());
      extensoField.setText(ve.toString());
    }


    private void bancoButtonActionPerformed(java.awt.event.ActionEvent evt)
    {
      BankEditor be = new BankEditor(db);
      JDialog bankDialog = new JDialog(((JFrame)this.getTopLevelAncestor()), "Editor de Bancos", true);
      bankDialog.setSize(BankEditor.framedim);
      int x = this.getLocationOnScreen().x;
      int y = this.getLocationOnScreen().y;
      bankDialog.setLocation((x + this.getWidth()/2 - bankDialog.getWidth()/2),
          (y + this.getHeight()/2 - bankDialog.getHeight()/2));
      bankDialog.setLayout(new TransparentLayout());
      bankDialog.add(be, new Rectangle(5, 5, be.getWidth(), be.getHeight()));
      bankDialog.setVisible(true);
      this.loadBanks();
    }


    private void chequesComboActionPerformed(ActionEvent e)
    {
      Object o = chequesBox.getSelectedItem();
      if(o == null || !(o instanceof Cheque)) return;
      selected = (Cheque) o;
      bancoBox.setSelectedItem(selected.getBanco());
      numberField.setText(String.valueOf(selected.getNumero()));
      moedaBox.setSelectedItem(selected.getMoeda());
      valorField.setText(Formatter.format(selected.getMoeda(), 2, selected.getValor(), 2));
      this.valorFieldActionPerformed(null);
      nominalField.setText(selected.getNominal());
      finalidadeField.setText(selected.getFinalidade());
      emissaoDate.setDate(new Date(selected.getDataEmissao().getTime()));
      futureDate.setDate(new Date(selected.getDataFutura().getTime()));
    }


    private void moedaButtonActionPerformed(java.awt.event.ActionEvent evt) {
      JDialog dialog = new JDialog((Frame)this.getTopLevelAncestor(),
          "Moedas", true);
      dialog.setSize(MoedaEditor.framedim);
      int x = this.getLocationOnScreen().x;
      int y = this.getLocationOnScreen().y;
      dialog.setLocation((x+this.getWidth()/2 - dialog.getWidth()/2),
          (y+this.getHeight()/2 - dialog.getHeight()/2));
      dialog.setLayout(new TransparentLayout());
      MoedaEditor me = new MoedaEditor(db);
      dialog.add(me, new Rectangle(5, 5, me.getWidth(), me.getHeight()));
      dialog.setVisible(true);
    }


    private void removerButtonActionPerformed(java.awt.event.ActionEvent evt) {
      if(selected == null) {
        setStatus("Nenhum cheque selecionado.");
        return;
      }

      db.delete(selected);
      loadCheques();
      loadBanks();
      loadMoedas();
      this.limparButtonActionPerformed(null);
      setStatus("Cheque removido com sucesso!");
    }


    private boolean checkBank()
    {
      Object o = bancoBox.getSelectedItem();
      if(o == null || !(o instanceof Banco)) {
        this.setStatus("Selecione um Banco.");
        return false;
      }
      return true;
    }


    private boolean checkMoeda()
    {
      Object o = moedaBox.getSelectedItem();
      if(o == null || !(o instanceof Moeda)) {
        this.setStatus("Selecione um tipo de Moeda.");
        return false;
      }
      return true;
    }


    private boolean checkNumero()
    {
      String s = numberField.getText();
      try {
        Integer.parseInt(s);
      } catch(NumberFormatException ex) {
        this.setStatus("Numero do cheque inv�lido.");
        return false;
      }
      return true;
    }


    private boolean checkValor()
    {
      this.valorFieldActionPerformed(null);
      return value >= 0;
    }


    private void gravarButtonActionPerformed(java.awt.event.ActionEvent evt) {
      if(!checkBank()) return;
      if(!checkMoeda()) return;
      if(!checkNumero()) return;
      if(!checkValor()) return;

      if(this.emissaoDate.getDate() == null) {
        this.setStatus("Informe a data de emiss�o do cheque.");
        return;
      }
      if(value < 0) {
        this.setStatus("Valor inv�lido.");
        return;
      }

      String acao = "alterado";
      if(selected == null) {
        selected = new Cheque();
        acao = "gravado";
      }

      selected.setBanco((Banco) bancoBox.getSelectedItem());
      selected.setMoeda((Moeda) moedaBox.getSelectedItem());
      selected.setNumero(Integer.parseInt(numberField.getText()));
      selected.setValor(value);
      selected.setNominal(nominalField.getText());
      nominalField.addText();
      db.store(nominalField.getSearchable());
      selected.setFinalidade(finalidadeField.getText());
      finalidadeField.addText();
      db.store(finalidadeField.getSearchable());
      selected.setDataEmissao(new com.power.utils.Date(emissaoDate.getDate().getTime()));
      if(futureDate.getDate() != null)
        selected.setDataFutura(
            new com.power.utils.Date(
            futureDate.getDate().getTime()));
      db.store(selected);
      this.loadCheques();
      chequesBox.setSelectedItem(selected);
      this.limparButtonActionPerformed(null);
      setStatus("Cheque "+ acao+ " com sucesso!");
    }


    private void limparButtonActionPerformed(java.awt.event.ActionEvent evt) {
      selected = null;
      numberField.setText("");
      valorField.setText("");
      nominalField.setText("");
      finalidadeField.setText("");
      emissaoDate.setDate(null);
      futureDate.setDate(null);
      extensoField.setText("");
      setStatus("");
    }


  public void setStatus(String status)
  {
    statusBar.setText(" "+ status);
    statusBar.repaint();
  }

  
  @Override
  public void propertyChange(PropertyChangeEvent evt) {
    if(evt.getPropertyName().equals(FindBox.PROP_NOTIFY))
      this.setStatus(evt.getOldValue() + ": " + evt.getNewValue());
  }


  // Variables declaration - do not modify
  private javax.swing.JComboBox bancoBox;
  private javax.swing.JButton bancoButton;
  private javax.swing.JLabel bancoLabel;
  private javax.swing.JLabel selcheque;
  private com.power.visual.BlackButton consultarButton;
  private org.jdesktop.swingx.JXDatePicker emissaoDate;
  private javax.swing.JLabel emissaoLabel;
  private static javax.swing.JTextField extensoField;
  private javax.swing.JLabel extensoLabel;
  private com.power.visual.FindBox finalidadeField;
  private javax.swing.JLabel finalidadeLabel;
  private org.jdesktop.swingx.JXDatePicker futureDate;
  private com.power.visual.BlackButton gravarButton;
  private javax.swing.JComboBox chequesBox;
  private javax.swing.JLabel lancFuturoLabel;
  private com.power.visual.BlackButton removerButton;
  private javax.swing.JComboBox moedaBox;
  private javax.swing.JButton moedaButton;
  private javax.swing.JLabel moedaLabel;
  private com.power.visual.FindBox nominalField;
  private javax.swing.JLabel nominalLabel;
  private javax.swing.JTextField numberField;
  private javax.swing.JLabel numberLabel;
  private javax.swing.JLabel statusBar;
  private com.power.visual.BlackLabel titleLabel;
  private javax.swing.JTextField valorField;
  private javax.swing.JLabel valorLabel;
  // End of variables declaration


  public static void main(String[] args)
  {
    JFrame f = new JFrame("ChequeEditor");
    f.setLayout(new TransparentLayout());
    f.setBounds(300, 100, 610, 443);
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    Configuration conf = new Configuration();
    conf.setDBFile("powercash.db");
    ChequeEditor ce = new ChequeEditor(conf.startDB());
    f.add(ce, new Rectangle(2, 2, 602, 400));

    f.setVisible(true);
  }

}
